/**
 * 
 */
package com.globallogic.training.university;

import java.util.*;

import com.globallogic.training.university.people.*;
import com.globallogic.training.university.study.*;
import com.globallogic.training.university.property.*;

/**
 * A <code>ScheduledItem</code> class represents an item of University Schedule
 * 
 * @author vasiliy.kulgaviy
 * 
 */
public class ScheduledItem implements Comparable<ScheduledItem>{
	private ScheduledTime scheduledTime;
	private final Set<Student> students = new HashSet<Student>();
	private Teacher teacher;
	private Course course;
	private Auditorium auditorium;

	/**
	 *  Constructs a new Schedule Item with specified parameters
	 *  
	 *  @param scheduledTime time of the Schedule Item
	 *  @param course course scheduled in the Scheduled Item
	 *  @param auditorium auditorium which the course is scheduled in
	 *  @param teacher teacher assigned to the course         
	 */
	public ScheduledItem(ScheduledTime scheduledTime, Course course,
			Auditorium auditorium, Teacher teacher) {
		this.scheduledTime = scheduledTime;
		this.course = course;
		this.auditorium = auditorium;
		this.teacher = teacher;
	}

	/**
	 * Returns the Scheduled Time of the Scheduled Item
	 * @return the scheduledTime
	 */
	public ScheduledTime getScheduledTime() {
		return scheduledTime;
	}

	/**
	 * Returns the teacher of of the Scheduled Item
	 * @return the teacher
	 */
	public Teacher getTeacher() {
		return teacher;
	}

	/**
	 * Returns the course of the Scheduled Item
	 * @return the course
	 */
	public Course getCourse() {
		return course;
	}

	/**
	 * Returns the auditorium of the Scheduled Item
	 * @return the auditorium
	 */
	public Auditorium getAuditorium() {
		return auditorium;
	}

	/**
	 * Assigns the student to the Scheduled Course and Auditorium
	 * @param student student to assign
	 */
	public void addStudent(Student student) {
		students.add(student);
	}

	/**
	 * Checks if the student is assigned to the Scheduled Item
	 * @param student student to determine if one is assigned
	 * @return true - if the student is assigned to the Item, otherwise - false 
	 */
	public boolean hasStudent(Student student) {
		return students.contains(student);
	}
	
	

	/* (non-Javadoc)
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	@Override
	public int compareTo(ScheduledItem otherScheduledItem) {
		int result = scheduledTime.compareTo(otherScheduledItem.getScheduledTime());
		
		Auditorium otherAuditorium = otherScheduledItem.getAuditorium();
		
		return result == 0 ? auditorium.getId().compareTo(otherAuditorium.getId()) : result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 37;
		int result = 17;
		result = prime * result
				+ ((auditorium == null) ? 0 : auditorium.hashCode());
		result = prime * result
				+ ((scheduledTime == null) ? 0 : scheduledTime.hashCode());

		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof ScheduledItem)) {
			return false;
		}
		
		ScheduledItem other = (ScheduledItem) obj;
		if (auditorium == null) {
			if (other.auditorium != null) {
				return false;
			}
		} else if (!auditorium.equals(other.auditorium)) {
			return false;
		}
	
		if (scheduledTime == null) {
			if (other.scheduledTime != null) {
				return false;
			}
		} else if (!scheduledTime.equals(other.scheduledTime)) {
			return false;
		}

		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return String.format(Strings.TO_STRING_SCHEDULED_ITEM,
				auditorium.toString(), course.toString(), teacher.toString());
	}
}
